// 采用双指针法。
// 核心思路是设置两个指针，让它们保持固定的间隔，
// 然后同时移动，直到前面的指针到达链表末尾，此时后面的指针就指向了要删除节点的前一个节点。


// 定义链表节点类
class ListNode {
  constructor(val = 0, next = null) {
    this.val = val;
    this.next = next;
  }
}

function removeNthFromEnd(head, n) {
  // 创建虚拟头节点，简化边界情况处理
  const dummy = new ListNode(0);
  dummy.next = head;
  let first = dummy;
  let second = dummy;

  // 让 first 指针先移动 n + 1 步
  for (let i = 0; i <= n; i++) {
    first = first.next;
  }

  // 同时移动 first 和 second 指针，直到 first 到达链表末尾
  while (first) {
    first = first.next;
    second = second.next;
  }

  // 删除倒数第 n 个节点
  second.next = second.next.next;

  // 返回新的头节点
  return dummy.next;
}